import numpy as np
import matplotlib.pyplot as plt


# 定义函数
def f(x_):
    return x_ ** 2 - 3 * x_


# 生成 x 值
x = np.linspace(-2, 2, 100)  # (100,)
y = f(x)  # (100,)

x0 = 1
y0 = f(x0)  # 计算 x = 1 处的函数值

slope = np.gradient(y, x)  # 各个点的斜率
# 找到 x0 对应的斜率索引，argmin()返回元素最小值所在的索引
# 这里x的值是递增的所以可以这样使用,不是递增的不可用
index = np.abs(x - x0).argmin()
point_slope = slope[index]  # (x0,y0)点对应的斜率
# y - y0 = k * (x - x0)
tangent_line = point_slope * (x - x0) + y0  # 计算切线方程

fig, axes = plt.subplots()

axes.plot(x, y, label='y = x^3 - x')  # 绘制曲线
axes.title.set_text('y = x^3 - x')
axes.plot(x, tangent_line, label='y = 3*x^2 - 1', linestyle='--')  # 绘制切线
axes.scatter(x0, y0, color='red', label=f'Point at x = {x0}')  # 绘制切点
axes.set_xlabel('x')
axes.set_ylabel('y')
axes.legend()  # 添加图例,需要在plot、scatter等绘图操作之后

plt.suptitle('Plot of y = x^3 - x and its tangent at x = 1')  # figure 添加标题

plt.grid(True)
plt.show()
